home *** CD-ROM | disk | FTP | other *** search
- /* ICMP header conversion routines
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include "global.h"
- #include "mbuf.h"
- #include "internet.h"
- #include "ip.h"
- #include "icmp.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: icmphdr.c,v 1.7 1996/08/29 12:11:16 root Exp root $";
- #endif
-
-
- /* Generate ICMP header in network byte order, link data, compute checksum */
- struct mbuf *
- htonicmp (icmp, data)
- struct icmp *icmp;
- struct mbuf *data;
- {
- struct mbuf *bp;
- register unsigned char *cp;
- int16 thechecksum;
-
- if ((bp = pushdown (data, ICMPLEN)) == NULLBUF)
- return NULLBUF;
- cp = bp->data;
-
- *cp++ = uchar(icmp->type);
- *cp++ = uchar(icmp->code);
- cp = put16 (cp, 0); /* Clear checksum */
- switch (icmp->type) {
- case ICMP_DEST_UNREACH:
- if (icmp->code == ICMP_FRAG_NEEDED) {
- /* Deering/Mogul max MTU indication */
- cp = put16 (cp, 0);
- cp = put16 (cp, icmp->args.mtu);
- } else
- cp = put32 (cp, 0L);
- break;
- case ICMP_PARAM_PROB:
- *cp++ = icmp->args.pointer;
- *cp++ = 0;
- cp = put16 (cp, 0);
- break;
- case ICMP_REDIRECT:
- cp = put32 (cp, icmp->args.address);
- break;
- case ICMP_ECHO:
- case ICMP_ECHO_REPLY:
- case ICMP_TIMESTAMP:
- case ICMP_TIME_REPLY:
- case ICMP_INFO_RQST:
- case ICMP_INFO_REPLY:
- cp = put16 (cp, icmp->args.echo.id);
- cp = put16 (cp, icmp->args.echo.seq);
- break;
- default:
- cp = put32 (cp, 0L);
- break;
- }
- /* Compute checksum, and stash result */
- thechecksum = cksum (NULLHEADER, bp, len_p (bp));
- cp = &bp->data[2];
- cp = put16 (cp, thechecksum);
-
- return bp;
- }
-
-
- /* Pull off ICMP header */
- int
- ntohicmp (icmp, bpp)
- struct icmp *icmp;
- struct mbuf **bpp;
- {
- char icmpbuf[8];
-
- if (icmp == (struct icmp *) NULL)
- return -1;
- if (pullup (bpp, (unsigned char *) icmpbuf, 8) != 8)
- return -1;
- icmp->type = icmpbuf[0];
- icmp->code = icmpbuf[1];
- switch (icmp->type) {
- case ICMP_DEST_UNREACH:
- /* Retrieve Deering/Mogul MTU value */
- if (icmp->code == ICMP_FRAG_NEEDED)
- icmp->args.mtu = get16 (&icmpbuf[6]);
- break;
- case ICMP_PARAM_PROB:
- icmp->args.pointer = uchar (icmpbuf[4]);
- break;
- case ICMP_REDIRECT:
- icmp->args.address = get32 (&icmpbuf[4]);
- break;
- case ICMP_ECHO:
- case ICMP_ECHO_REPLY:
- case ICMP_TIMESTAMP:
- case ICMP_TIME_REPLY:
- case ICMP_INFO_RQST:
- case ICMP_INFO_REPLY:
- icmp->args.echo.id = get16 (&icmpbuf[4]);
- icmp->args.echo.seq = get16 (&icmpbuf[6]);
- break;
- default:
- break;
- }
- return 0;
- }
-